local machine = require('statemachine')
dbg = require('debugger')

local fsm = machine.create({
  initial = 'userNameNotTyped',
  events = {
    { name = 'typeUsername',    from = 'userNameNotTyped',  to = { 
                                                                   TRUE  = 'passwordNotTyped', 
                                                                   FALSE = 'error'
                                                                 }   },
    { name = 'typePassword',    from = 'passwordNotTyped',  to = { 
                                                                   TRUE  = 'imageCodeNotTyped', 
                                                                   FALSE = 'error'
                                                                 }   },
    { name = 'typeImageCode',   from = 'imageCodeNotTyped', to = { 
                                                                   TRUE  = 'smsCodeNotTyped', 
                                                                   FALSE = 'error'
                                                                 }   }, 
    { name = 'typeSmsCode',     from = 'smsCodeNotTyped',   to = { 
                                                                   TRUE  = 'allTyped', 
                                                                   FALSE = 'error'
                                                                 }   },
    { name = 'inputError',      from = 'error',             to = 'finished'              },
    -- { name = 'retryTimesLimit',      from = '*',             to = 'finished'              },
  },
  callbacks = {

      -- 事件前
      onbeforetypeUsername   = function(self, event, from, to, msg) 
          print("输入用户名前："..self.current)
          -- print("    检查用户名框是否存在")
          -- return false
      end,
      -- 旧状态转移前
      onleaveuserNameNotTyped   = function(self, event, from, to, msg) 
          print("状态转移前："..self.current)  
      end,
      onchecktypeUsername = function(self, event, from, to, msg)
          print("用户名校验通过")
          return to["FALSE"]
      end,
      -- 进入新状态
      onenteruserNameNotTyped   = function(self, event, from, to, msg) 
          print("改变状态为："..self.current)  
      end,

      -- 事件发生后
      onaftertypeUsername   = function(self, event, from, to, msg) 
          print("输入用户名后："..self.current)  
      end,


      onbeforetypePassword   = function(self, event, from, to, msg) 
          print("输入密码前："..self.current)
          -- print("    检查密码框是否存在")
          -- return false
      end,
      onleavepasswordNotTyped   = function(self, event, from, to, msg) 
          print("状态转移前："..self.current)    
      end,
      onchecktypePassword = function(self, event, from, to, msg)
          print("密码校验通过")
          return to["TRUE"]
      end,
      onenterpasswordNotTyped   = function(self, event, from, to, msg) 
          print("改变状态为："..self.current)    
      end,
      onaftertypePassword   = function(self, event, from, to, msg) 
          print("输入密码后："..self.current)    
      end,



      onbeforetypeImageCode  = function(self, event, from, to, msg) 
          print("输入图片验证码前："..self.current)
          -- print("    检查图片验证码框是否存在")
          -- return false
      end,  
      onleaveimageCodeNotTyped  = function(self, event, from, to, msg) 
          print("状态转移前："..self.current) 
          -- self:inputError()
          -- dbg()
          -- self:inputError()
          -- self:cancelTransition(event)
          -- return false
      end,
      onchecktypeImageCode = function(self, event, from, to, msg)
          print("图片验证码校验通过")
          return to["TRUE"]
      end,
      onenterimageCodeNotTyped  = function(self, event, from, to, msg) 
          print("改变状态为："..self.current)    
      end,
      onaftertypeImageCode  = function(self, event, from, to, msg) 
          print("输入图片验证码后："..self.current)    
      end,


      onbeforetypeSmsCode    = function(self, event, from, to, msg) 
          print("输入短信验证码前："..self.current)
          -- print("    检查短信验证码框是否存在")
          return false
      end,
      onleavesmsCodeNotTyped    = function(self, event, from, to, msg) 
          print("状态转移前："..self.current)    
      end,
      onchecksmsCodeNotTyped  = function(self, event, from, to, msg)
          print("短信验证码校验通过")
          return to["TRUE"]
      end,
      onentersmsCodeNotTyped    = function(self, event, from, to, msg) 
          print("改变状态为："..self.current)    
      end,
      onaftertypeSmsCode    = function(self, event, from, to, msg) 
          print("输入短信验证码后："..self.current)    
      end,

      -- 输入有误
      onbeforeinputError    = function(self, event, from, to, msg)
          print((msg or "nil").."|"..self.previous.."|"..from..":输入有误："..self.current)  
      end,
      oninputError    = function(self, event, from, to, msg)
          print((msg or "nil").."|"..self.previous.."|"..from..":输入有误："..self.current)  
      end,
      onstatechange   = function(self, event, from, to, msg)
          print("状态又变了|"..self.previous.."|"..self.current)
      end
  }
})

-- print("当前状态："..fsm.current)
-- print("当前状态转移事件："..(fsm.currentTransitioningEvent or "nil"))
-- print("是否是初始状态："..tostring(fsm:is("init")))
-- print("能start："..tostring(fsm:can("start")))
-- print("不能start："..tostring(fsm:cannot("start")))
-- print("------------------------")

-- fsm:start()
-- fsm:stop()


-- print("当前状态："..fsm.current)
-- print("当前状态转移事件："..(fsm.currentTransitioningEvent or "nil"))
-- print("是否是初始状态："..tostring(fsm:is("init")))
-- print("能start："..tostring(fsm:can("start")))
-- print("不能start："..tostring(fsm:cannot("start")))
-- print("------------------------")
function main()
  do
   local repeatTimes = 3
   local tempState
   while not fsm:is("allTyped") do

      print("------------------------")
      print("上一次循环的状态："..(tempState or "nil").."|当前状态："..fsm.current)
      if tempState == fsm.current then
          repeatTimes = repeatTimes - 1;
      end
      if repeatTimes == 3 then
          tempState = fsm.current
      end

      if repeatTimes > 0 then 
        if fsm:is("userNameNotTyped") then
            fsm:typeUsername()
        elseif fsm:is("passwordNotTyped") then
            fsm:typePassword()
        elseif fsm:is("imageCodeNotTyped") then
          -- dbg()
            fsm:typeImageCode()
        elseif fsm:is("smsCodeNotTyped") then
            fsm:typeSmsCode()
        else
            dbg()
            fsm:inputError()
            break;
        end
      else
        fsm.current = "error"
        fsm.previous = tempState
        fsm:inputError()
        break;
      end
      
   end
  end
end

main()
fsm:todot("new.dot")


